package system

import (
	"context"
	"os"
	"os/exec"

	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/util/guid"
	"github.com/sagoo-cloud/sagooiot/api/v1/system"
	"github.com/sagoo-cloud/sagooiot/internal/consts"
	"github.com/sagoo-cloud/sagooiot/internal/dao"
	"github.com/sagoo-cloud/sagooiot/internal/model"
	"github.com/sagoo-cloud/sagooiot/internal/service"
)

type sSystemApplication struct{}

func sSystemApplicationNew() *sSystemApplication {
	return &sSystemApplication{}
}
func init() {
	service.RegisterSystemApplication(sSystemApplicationNew())
}

// GetApplicationList 获取列表数据
func (s *sSystemApplication) GetApplicationList(ctx context.Context, in *model.GetApplicationListInput) (total, page int, list []*model.ApplicationOutput, err error) {
	err = g.Try(ctx, func(ctx context.Context) {
		m := dao.Application.Ctx(ctx)
		if in.KeyWord != "" {
			m = m.WhereLike(dao.Application.Columns().Name, "%"+in.KeyWord+"%")
		}
		total, err = m.Count()
		if err != nil {
			err = gerror.New("获取总行数失败")
			return
		}
		page = in.PageNum
		if in.PageSize == 0 {
			in.PageSize = consts.PageSize
		}
		err = m.Page(page, in.PageSize).Order("created_at desc").Scan(&list)
		if err != nil {
			err = gerror.New("获取数据失败")
		}
	})
	return
}

// GetApplicationById 获取指定ID数据
func (s *sSystemApplication) GetApplicationById(ctx context.Context, id int) (out *model.ApplicationOutput, err error) {
	err = dao.Application.Ctx(ctx).Where(dao.Application.Columns().Id, id).Scan(&out)
	return
}

// AddApplication 添加数据
func (s *sSystemApplication) AddApplication(ctx context.Context, in model.ApplicationAddInput) (err error) {
	in.AppId = guid.S()
	_, err = dao.Application.Ctx(ctx).Insert(in)
	return
}

// EditApplication 修改数据
func (s *sSystemApplication) EditApplication(ctx context.Context, in model.ApplicationEditInput) (err error) {
	dao.Application.Ctx(ctx).FieldsEx(dao.Application.Columns().Id, dao.Application.Columns().AppId).Where(dao.Application.Columns().Id, in.Id).Update(in)
	return
}

// DeleteApplication 删除数据
func (s *sSystemApplication) DeleteApplication(ctx context.Context, Ids []int) (err error) {
	_, err = dao.Application.Ctx(ctx).Delete(dao.Application.Columns().Id+" in (?)", Ids)
	return
}

// SetApplicationStatus 启动/禁用 应用管理
func (s *sSystemApplication) SetApplicationStatus(ctx context.Context, req *system.SetApplicationStatusReq) (res *system.SetApplicationStatusRes, err error) {
	_, err = dao.Application.Ctx(ctx).Where(dao.Application.Columns().Id, req.Id).Data(map[string]int{"status": req.Status}).Update()
	return
}

// Restartpplication 重启应用
func (s *sSystemApplication) RestartApplication(ctx context.Context, req *system.RestartApplicationListReq) (res *system.RestartApplicationListRes, err error) {

	argv0, err := exec.LookPath(os.Args[0])
	if err != nil {
		return nil, err
	}

	os.Setenv("RESTART", "1")
	var originalWD, _ = os.Getwd()
	process, err := os.StartProcess(argv0, os.Args, &os.ProcAttr{
		Dir:   originalWD,
		Env:   os.Environ(),
		Files: []*os.File{os.Stdin, os.Stdout, os.Stderr},
	})
	if err != nil {
		return nil, err
	}
	g.Log().Info(ctx, "application upgrade success pid = ", process.Pid)

	return
}
